from abc import abstractmethod

from hruntools.parser.parservisitor.visitorbase import Element, Visitor, SingletonMeta


class Row(Element):
    def __init__(self, index=0, row=[]):
        if len(row) == 0:
            return
        self.index = index
        # self.rowList = []
        self.type = 'ValueLine'
        # self.Fieldrow = None

        self._typeit(row)

        if self.type in ['FieldsLine', 'ValueLine']:
            del row[0]
        self.row = row

        # self.createField(row)

    def _typeit(self, row):
        # 判断行类型
        if row[0] == '=':  # 字段
            self.type = 'FieldsLine'
        elif row[0] == '' and row[1] == '':  # 空行
            self.type = 'BlankLine'
        elif row[0] != '' and row[1] == '':  # 类型 行
            self.type = row[0] + 'Line'

    def __str__(self):
        return str(self.row)

    def __getitem__(self, index):
        return self.row[index]
        # if self.type in ['configLine', 'teststepsLine', 'testcasesLine', 'FieldsLine']:
        #     return self.row[index]
        # else:
        #     return self.rowList[index]


class RowsVisitor(Visitor):
    def __init__(self):
        self.currentIndex = 0
        self.totalRow = 0

    def visit_Row(self, element):
        if element.type == 'FieldsLine':
            print(dict(element.iter_fields()))

            # for xx in element.iter_fields():
            #     print(xx)
        else:
            print(element)

    def visit_blankrow(self, row):
        print('=========blank row ======')

    def row_next(self, addnum=1):
        self.currentIndex += addnum

    def row_get_values(self):
        return Row(self.currentIndex, self.rowvalues())

    def row_next_values(self):
        self.row_next()
        return self.row_get_values()

    def scanFile(self):
        # 获取总行数
        # self.rosw = self.sheet.nrows
        while self.currentIndex < self.totalRow:
            self.visit(self.row_get_values())

            self.row_next()

    @abstractmethod
    def rowvalues(self):
        pass


class SheetVisitor(RowsVisitor):

    def __init__(self, sheet):
        super().__init__()
        self.sheet = sheet

        from hruntools.parser.parservisitor.TCobjects import TC_Blocks_rec
        self.tcblock = TC_Blocks_rec()

    def visit(self, element):
        # 过滤空行
        # if sheet.row_values(self.currentIndex, 0, 1)[0] != '' or sheet.row_values(self.currentIndex, 1, 2)[0] != '':
        if element.type not in ['BlankLine']:
            if element.type == 'configLine':
                self.visit_config(element)
            elif element[0] in ['teststeps']:
                self.visit_teststep(element)
            elif element[0] in ['testcases']:
                self.visit_testcases(element)
            else:
                self.visit_Row(element)
        else:
            self.visit_blankrow(element)

    def visit_config(self, row):
        if row.type != 'configLine': return
        print('config is here')

        xconfig = self.tcblock.create_config(self.row_next_values(), self.row_next_values())

        # print(dict(xconfig.iter_values()))

    def visit_teststep(self, row):
        if row.type != 'teststepsLine': return
        print('teststep is here')

        xrecord = self.tcblock.create_record(totalcount=self.totalRow,
                                             func_cindex=lambda: self.currentIndex,
                                             func_nextvalues=lambda: self.row_next_values())
        # for xx in xrecord.iter_records():
        #     print(dict(xx))

    def visit_testcases(self, row):
        if row.type != 'testcasesLine': return
        print('testcases is here')

        xrecord = self.tcblock.create_testcases(totalcount=self.totalRow,
                                                func_cindex=lambda: self.currentIndex,
                                                func_nextvalues=lambda: self.row_next_values())

    def rowvalues(self):
        return self.sheet.row_values(self.currentIndex)

    def scanSheet(self):
        # 获取总行数
        self.totalRow = self.sheet.nrows
        self.scanFile()

        # self.tcblock.display()
        return self.tcblock.finejson()

    def get_sheet_json(self):

        return self.tcblock.to_dict()

    def get_sheet_string(self):
        return self.tcblock.finejson()


class ExcelVisitor(metaclass=SingletonMeta):
    # __metaclass__ = SingletonMeta

    def __init__(self, wb=None):
        if wb is not None:
            self.workbook = wb

    def init(self, wb):
        self.workbook = wb

        return self

    # def get_sheet_json(self, sheetname):
    #     return self.sv.get_sheet_json()
    #
    # def get_sheet_string(self):
    #     return self.sv.get_sheet_string()
    #     # return SheetVisitor(self.workbook.sheet_by_name(sheetname)).scanSheet()

    def sheetscan(self, sheetname):
        sv = SheetVisitor(self.workbook.sheet_by_name(sheetname))
        sv.scanSheet()
        return sv

    def scansheet_json(self, sheetname):
        return self.sheetscan(sheetname).get_sheet_json()

    def scansheet_string(self, sheetname):
        return self.sheetscan(sheetname).get_sheet_string()

    def displayExcel(self, sheetname):
        xxx = self.scansheet_string(sheetname)

        print(xxx)
